#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

#include <cstdlib>
#include <cstring>
#include <iostream>
#include <string>

#define N 2

#define NUM 1024

using namespace std;

namespace PIC {

void Write(int wfd) {
  char buff[NUM];
  pid_t self = getpid();
  string s = "I am a child";
  int number = 0;
  while (true) {
    buff[0] = 0;  // 字符串清空 (为读者展示该数组将被视为一个字符串)

    snprintf(buff, sizeof(buff), "%s-%d-%d", s.c_str(), self, number++);
    // cout << buff << endl;

    // 向父进程进行通信
    write(wfd, buff, strlen(buff));  // 进行写入时数据不作为一个字符串
    // sleep(4);
    sleep(1);
  }
}

// void Write(int wfd) {
//   char buff[NUM];
//   int number = 0;
//   while (true) {
//     char c = 'c';
//     write(wfd, &c, 1);  // 进行写入时数据不作为一个字符串
//     number++;
//     cout << number << endl;
//   }
// }

// void Read(int rfd) { 
//   // sleep(50);

//   char buff[NUM];
//   buff[0] = 0;
//   while (true) {
//     buff[0] = 0;  // 字符串清空 (为读者展示该数组将被视为一个字符串)
//     ssize_t n = read(rfd, buff, sizeof(buff));
//     if (n > 0) {
//       buff[n] = 0;  // 需要打印时将需要称为一个字符串 需要添加'\0'
//       cout << "parent process get a massage [" << getpid() << "]# " << buff
//            << endl;
//     }
//     // sleep(100);
//   }
// }

void Read(int rfd) {
  int cnt = 0;
  char buff[NUM];
  buff[0] = 0;
  while (true) {
    buff[0] = 0;  // 字符串清空 (为读者展示该数组将被视为一个字符串)
    ssize_t n = read(rfd, buff, sizeof(buff));
    if (n > 0) {
      buff[n] = 0;  // 需要打印时将需要称为一个字符串 需要添加'\0'
      cout << "parent process get a massage [" << getpid() << "]# " << buff
           << endl;
    }
    if (++cnt >= 3) break;
  }
}

}  // namespace PIC
int main() {
  int pipefd[N] = {0};
  int n = pipe(pipefd);
  if (n < 0) {
    cerr << "pipe error" << endl;
    exit(-1);
  }

  pid_t id = fork();
  if (id < 0) {
    cerr << "fork error" << endl;
    exit(-1);
  }
  /*
    child -> parent
    pipefd[0] -- 'r'
    pipefd[1] -- 'w'
  */

  if (id == 0) {
    // child - `w`
    close(pipefd[0]);   
    // IPC code
    PIC::Write(pipefd[1]);
    exit(0);
  }

  // parent - `r`
  close(pipefd[1]);
  // IPC code
  PIC::Read(pipefd[0]);
  close(pipefd[0]);
  sleep(3);//观察僵尸状态
  int status = 0;
  pid_t rid = waitpid(id, &status, 0);
  cout << "Parent process [" << getpid()
       << "]@ waited for child process sucessed " << endl
       << "Child process terminated by signal " << WTERMSIG(status) << endl;

  if (rid < 0) return 3;

  return 0;
}